package com.codeest.geeknews.ui.main.fragment;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.os.SystemClock;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.codeest.geeknews.R;
import com.codeest.geeknews.base.BaseFragment;
import com.codeest.geeknews.media.music.IMediaPlaybackService;
import com.codeest.geeknews.media.music.MediaPlaybackService;
import com.codeest.geeknews.media.music.MusicUtils;
import com.codeest.geeknews.model.bean.MusicInfo;
import com.codeest.geeknews.presenter.main.LastfmPresenter;
import com.codeest.geeknews.ui.main.activity.MainActivity3;
import com.codeest.geeknews.ui.main.adapter.LastfmMusicListAdapter;
import com.codeest.geeknews.util.StatusBarUtil;
import com.codeest.geeknews.util.ImageUtil;
import com.codeest.geeknews.widget.RotateableRoundImageView;
import com.codeest.geeknews.widget.discrete.ScaleTransformerExt;
import com.yarolegovich.discretescrollview.DiscreteScrollView;
import com.yarolegovich.discretescrollview.Orientation;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.OnClick;

import static com.codeest.geeknews.media.music.MediaPlaybackService.META_CHANGED;


/**
 * 播放器Fragment
 * 启动Fragment——>屏幕锁屏——>屏幕解锁——>切换到其他的Fragment——>回到桌面——>回到应用——>退出Fragment
 * (1)、启动Fragment
 * onAttach()->onCreate()->onCreateView()->onActivityCreated()->onStart()->onResume()
 * (2)、屏幕锁屏
 * onPause()->onStop()
 * (3)、屏幕解锁
 * onStart()->onResume()
 * (4)、切换Fragment
 * onPause()->onStop()->onDestroyView()
 * (5)、返回原先的Fragment
 * onCreateView->onActivityCreated()->onStart()->onResume()
 * (6)、回到桌面
 * onPause()->onSaveInstanceState()->onStop()
 * (7)、回到Activity
 * onStart()->onResume()
 * (8)、退出Fragment
 * onPause()->onStop()->onDestroyView()->onDestroy()->onDetach()
 */
public class LasfmMusicFragment extends BaseFragment<LastfmPresenter> implements DiscreteScrollView.OnItemChangedListener<RecyclerView.ViewHolder>,
        ServiceConnection, LastfmMusicListAdapter.OnMusicInfoListener {

    @BindView(R.id.toolbar)
    Toolbar mToolbar;
    @BindView(R.id.list)
    DiscreteScrollView mList;
    @BindView(R.id.bgImage)
    ImageView bgImage;
    @BindView(R.id.btn_pause)
    ImageButton btn_pause;
    @BindView(R.id.position_text)
    TextView mCurrentTime;
    @BindView(R.id.duration_text)
    TextView mTotalTime;
    @BindView(R.id.seek_bar)
    ProgressBar mProgress;

    private MusicInteraction mListener;
    private long[] list;
    private IMediaPlaybackService mService = null;
    private MusicUtils.ServiceToken mToken;
    private int mCurrentPosition = 0;


    private static final int REFRESH = 1;
    private static final int QUIT = 2;


    private long mPosOverride = -1;
    private boolean mFromTouch = false;
    private long mLastSeekEventTime;
    private long mDuration;
    private int seekmethod;
    private boolean paused;

    private List<MusicInfo> mDatas;
    private LastfmMusicListAdapter mAdapter;
    private boolean isServiceHadBinded;
    private BroadcastReceiver mStatusListener = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(META_CHANGED)) {
                // redraw the artist/title info and
                // set new max for progress bar
                updateTrackInfo();
                setSeekControls();
                setPauseButtonImage();
                queueNextRefresh(1);
                setPager();
                updateExtra();
            } else if (action.equals(MediaPlaybackService.PLAYSTATE_CHANGED)) {
                setPauseButtonImage();
            }
        }
    };
    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case REFRESH:
                    long next = refreshNow();
                    queueNextRefresh(next);
                    break;

                case QUIT:
                    // This can be moved back to onCreate once the bug that prevents
                    // Dialogs from being started from onCreate/onResume is fixed.
                    new AlertDialog.Builder(getActivity())
                            .setTitle(R.string.service_start_error_title)
                            .setMessage(R.string.service_start_error_msg)
                            .setPositiveButton(android.R.string.ok,
                                    new DialogInterface.OnClickListener() {
                                        public void onClick(DialogInterface dialog, int whichButton) {
                                            //finish();
                                        }
                                    })
                            .setCancelable(false)
                            .show();
                    break;

                default:
                    break;
            }
        }
    };
    private SeekBar.OnSeekBarChangeListener mSeekListener = new SeekBar.OnSeekBarChangeListener() {
        public void onStartTrackingTouch(SeekBar bar) {
            mLastSeekEventTime = 0;
            mFromTouch = true;
        }

        public void onProgressChanged(SeekBar bar, int progress, boolean fromuser) {
            if (!fromuser || (mService == null)) return;
            long now = SystemClock.elapsedRealtime();
            if ((now - mLastSeekEventTime) > 250) {
                mLastSeekEventTime = now;
                mPosOverride = mDuration * progress / 1000;
                try {
                    mService.seek(mPosOverride);
                } catch (RemoteException ex) {
                }

                // trackball event, allow progress updates
                if (!mFromTouch) {
                    refreshNow();
                    mPosOverride = -1;
                }
            }
        }

        public void onStopTrackingTouch(SeekBar bar) {
            mPosOverride = -1;
            mFromTouch = false;
        }
    };

    @OnClick(R.id.btn_pause)
    public void onPauseClick(ImageButton button) {
        pauseOrPlay(button);
    }


    @OnClick(R.id.btn_pre)
    public void onPreClick() {
        if (mList.getCurrentItem() > 0) {//防止越界
            mList.smoothScrollToPosition(mList.getCurrentItem() - 1);
        }
    }


    @OnClick(R.id.btn_next)
    public void onNextClick() {
        if (mList.getCurrentItem() < mDatas.size() - 1) {//防止越界
            mList.smoothScrollToPosition(mList.getCurrentItem() + 1);
        }
    }

    private void pauseOrPlay(ImageButton button) {
        try {
            if (mService.isPlaying()) {
                mService.pause();
            } else {
                mService.play();
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    private void next() {
        try {
            mService.next();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    private void pre() {
        try {
            mService.prev();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }


    @Override
    protected void initInject() {
        getFragmentComponent().inject(this);
    }

    @Override
    protected int getLayoutId() {
        return R.layout.fragment_music;
    }

    @Override
    protected void initEventAndData() {
        //
        ArrayList<String> urls = new ArrayList<>();
        urls.add("http://mp3.haoduoge.com/s/2017-08-22/1503408859.mp3");
        urls.add("http://mp3.haoduoge.com/s/2017-08-23/1503435510.mp3");
        urls.add("http://mp3.haoduoge.com/s/2017-05-20/1495254760.mp3");
        urls.add("http://mp3.haoduoge.com/s/2017-08-01/1501578642.mp3");
        urls.add("http://mp3.haoduoge.com/s/2017-08-01/1501578375.mp3");
        urls.add("http://mp3.haoduoge.com/s/2017-08-01/1501561720.mp3");
        mDatas = new ArrayList<>();
        for (int i = 0; i < urls.size(); i++) {
            mDatas.add(new MusicInfo(i, urls.get(i)));
        }
        //
        mList.addOnItemChangedListener(this);
        mList.setOrientation(Orientation.HORIZONTAL);
        //infiniteAdapter = InfiniteScrollAdapter.wrap(new LastfmMusicListAdapter(data));//无线循环Adapter
        //mRecyclerView.setAdapter(infiniteAdapter);
        mAdapter = new LastfmMusicListAdapter(mDatas, mPresenter, this);//无循环Adapter
        mList.setAdapter(mAdapter);
        //mRecyclerView.setItemTransitionTimeMillis(DiscreteScrollViewOptions.getTransitionTime());
        mList.setItemTransformer(new ScaleTransformerExt.Builder()
                .setMinScale(0.5f)
                .build());

        list = new long[urls.size()];
        for (int i = 0; i < urls.size(); i++) {
            list[i] = MusicUtils.insert(mActivity, urls.get(i));
        }
        //mToken = MusicUtils.bindToService(mActivity, this);
        //
        IntentFilter f = new IntentFilter();
        f.addAction(MediaPlaybackService.PLAYSTATE_CHANGED);
        f.addAction(META_CHANGED);
        mActivity.registerReceiver(mStatusListener, new IntentFilter(f));
        mProgress.setMax(1000);
        if (mProgress instanceof SeekBar) {
            SeekBar seeker = (SeekBar) mProgress;
            seeker.setOnSeekBarChangeListener(mSeekListener);
        }

    }


    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        setToolBar(mToolbar, "");
        mToolbar.setBackgroundResource(android.R.color.transparent);
        //状态栏透明和间距处理
        {
            StatusBarUtil.setPaddingSmart(mActivity, mToolbar);
        }
    }


    /**
     * 之所以不直接设置icon(mToolbar.setNavigationIcon(R.drawable.icon_toolbar_back);)是为了使用系统默认的
     *
     * @param toolbar
     * @param title
     */
    protected void setToolBar(Toolbar toolbar, String title) {
        TextView titleView = ((TextView) toolbar.findViewById(R.id.title));
        if (titleView != null) {
            titleView.setText(title);
            toolbar.setTitle("");
        } else {
            toolbar.setTitle(title);
        }
        ((AppCompatActivity) mActivity).setSupportActionBar(toolbar);
        ((AppCompatActivity) mActivity).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        ((AppCompatActivity) mActivity).getSupportActionBar().setDisplayShowHomeEnabled(true);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (mListener instanceof MainActivity3) {
                    mListener.toggleMenu();
                } else {
                    mActivity.finish();
                }
            }
        });
    }

    @Override
    public void onAttach(Activity context) {
        super.onAttach(context);
        if (context instanceof MusicInteraction) {
            mListener = (MusicInteraction) context;
        } else {
            throw new RuntimeException(context.toString() + " must implement MusicInteraction");
        }
    }

    //http://m.blog.csdn.net/u010290494/article/details/43836145
    @Override
    public void onStart() {
        super.onStart();
        paused = false;
        mToken = MusicUtils.bindToService(mActivity, this);
        if (mToken == null) {
            // something went wrong
            mHandler.sendEmptyMessage(QUIT);
        }

        IntentFilter f = new IntentFilter();
        f.addAction(MediaPlaybackService.PLAYSTATE_CHANGED);
        f.addAction(META_CHANGED);
        mActivity.registerReceiver(mStatusListener, new IntentFilter(f));
        updateTrackInfo();
        long next = refreshNow();
        queueNextRefresh(next);
    }

    @Override
    public void onResume() {
        super.onResume();
        updateTrackInfo();
        setPauseButtonImage();
    }

    @Override
    public void onPause() {
        super.onPause();
        //dismissLoadingDialog();
    }

    @Override
    public void onStop() {
        paused = true;
        mHandler.removeMessages(REFRESH);
        mActivity.unregisterReceiver(mStatusListener);
        MusicUtils.unbindFromService(mToken);
        try {
            mService.stop();
            mService = null;
        } catch (RemoteException e) {
            e.printStackTrace();
        }

        super.onStop();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }


    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        mService = IMediaPlaybackService.Stub.asInterface(service);
        if (isServiceHadBinded) {
            return;
        }
        try {
            mService.open(list, 0);
            isServiceHadBinded = true;
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        try {
            mService.stop();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }


    private void queueNextRefresh(long delay) {
        if (!paused) {
            Message msg = mHandler.obtainMessage(REFRESH);
            mHandler.removeMessages(REFRESH);
            mHandler.sendMessageDelayed(msg, delay);
        }
    }

    private long refreshNow() {
        if (mService == null)
            return 500;
        try {
            long pos = mPosOverride < 0 ? mService.position() : mPosOverride;
            if ((pos >= 0)) {
                mCurrentTime.setText(MusicUtils.makeTimeString(mActivity, pos / 1000));
                if (mDuration > 0) {
                    mProgress.setProgress((int) (1000 * pos / mDuration));
                } else {
                    mProgress.setProgress(0);
                }
            } else {
                mCurrentTime.setText("--:--");
                mProgress.setProgress(0);
            }
            // calculate the number of milliseconds until the next full second, so
            // the counter can be updated at just the right time
            long remaining = 1000 - (pos % 1000);

            // approximate how often we would need to refresh the slider to
            // move it smoothly
            int width = mProgress.getWidth();
            if (width == 0) width = 320;
            long smoothrefreshtime = mDuration / width;

            if (smoothrefreshtime > remaining) return remaining;
            if (smoothrefreshtime < 20) return 20;
            return smoothrefreshtime;
        } catch (RemoteException ex) {
            ex.printStackTrace();
        }
        return 500;
    }

    private void updateExtra() {
//        try {
//            if (mService == null || mService.getMediaUri() == null || mService.getMediaUri().equals("")) {
//                return;
//            }
//            Log.i("LasfmMusicFragment", mService.getMediaUri());
//            VideoUtil.getMetadata(mService.getMediaUri(), new VideoUtil.Callback() {
//                @Override
//                public void onMetadata(final FFmpegMediaMetadataRetriever mmr) {
//                    final Bitmap bitmap = mmr.getFrameAtTime();
//                    HashMap<String, String> all = mmr.getMetadata().getAll();//不要放到runOnUiThread执行
//                    for (Map.Entry<String, String> o : all.entrySet()) {
//                        String key = o.getKey();
//                        String val = o.getValue();
//                        Log.e("LasfmMusicFragment", key + "=" + val);
//                    }
//                    final String artist = mmr.getMetadata().getString(FFmpegMediaMetadataRetriever.METADATA_KEY_TITLE);//不要放到runOnUiThread执行
//                    getActivity().runOnUiThread(new Runnable() {
//                        @Override
//                        public void run() {
//                            setToolBar(mToolbar, artist);
//                            bgImage.setImageBitmap(bitmap);
//                        }
//                    });
//                }
//            });
//        } catch (RemoteException e) {
//            e.printStackTrace();
//        }
    }

    private void updateTrackInfo() {
        if (mService == null) {
            return;
        }
        try {
            mDuration = mService.duration();
            mTotalTime.setText(MusicUtils.makeTimeString(mActivity, mDuration / 1000));
        } catch (RemoteException ex) {
            //finish();
        }
    }

    private void setSeekControls() {
        if (mService == null) {
            return;
        }

        try {
            if (mService.duration() > 0) {
                mProgress.setEnabled(true);
            } else {
                mProgress.setEnabled(false);
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }


    private void setPauseButtonImage() {
        try {
            if (mService != null && mService.isPlaying()) {
                btn_pause.setImageResource(R.drawable.selector_player_btn_pause);
            } else {
                btn_pause.setImageResource(R.drawable.selector_player_btn_play);
            }
        } catch (RemoteException ex) {
            ex.printStackTrace();
        }
    }

    private void setPager() {
        if (mService == null) {
            return;
        }
        try {
            int position = mService.getQueuePosition() + 1;
            //mPager.setCurrentItem(position, false);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    private RotateableRoundImageView mPreImageView;

    @Override
    public void onCurrentItemChanged(@Nullable RecyclerView.ViewHolder viewHolder, int adapterPosition) {
        //int positionInDataSet = infiniteAdapter.getRealPosition(adapterPosition);
        //Glide.with(this).load(data.get(adapterPosition).getImage())
        //.bitmapTransform(new BlurTransformation(mActivity, 25), new CenterCrop(mActivity))
        //.bitmapTransform(new CropCircleTransformation(this))
        //.into(bgImage);
        //
        if (viewHolder != null && mCurrentPosition != adapterPosition) {
            if (mPreImageView != null) {
                mPreImageView.stopRotation();
            }
            RotateableRoundImageView imageView = (RotateableRoundImageView) viewHolder.itemView.findViewById(R.id.image);
            Drawable _old = new BitmapDrawable(ImageUtil.getBitmapFromDrawable(bgImage.getDrawable()));
            Bitmap bitmap = ImageUtil.getBitmapFromDrawable(imageView.getDrawable());
            Drawable _new;
            if (bitmap == null) {
                _new = new ColorDrawable(getResources().getColor(android.R.color.black));
            } else {
                _new = new BitmapDrawable(bitmap);
            }
            //背景图片渐变
            alphaBackground(_old, _new);
            //设置标题
            setToolBar(mToolbar, (String) imageView.getTag(R.id.tag_title));
            //旋转
            imageView.startRotation();
            //
            mPreImageView = imageView;
            //
            if (mCurrentPosition < adapterPosition) {
                next();
            } else {
                pre();
            }
            mCurrentPosition = adapterPosition;
        }
    }

    /**
     * 背景图片渐变
     */
    private void alphaBackground(Drawable _old, Drawable _new) {
        if (_old == null) {
            bgImage.setImageDrawable(_new);
        } else {
            //渐变切换
            TransitionDrawable td = new TransitionDrawable(new Drawable[]{_old, _new});
            bgImage.setImageDrawable(td);
            td.startTransition(300);
        }
    }

    @Override
    public void onImageLoaded(RecyclerView.ViewHolder holder, int position, String url) {
        if (mCurrentPosition == position) {
            Glide.with(this)
                    .load(url)
                    .into(bgImage);
        }

    }

    @Override
    public void onMetadata(RecyclerView.ViewHolder holder, int position, final String album, String artist) {
        if (mCurrentPosition == position) {
            mToolbar.post(new Runnable() {
                @Override
                public void run() {
                    setToolBar(mToolbar, album);
                }
            });
        }
    }


    public interface MusicInteraction {
        void toggleMenu();
    }
}

